package com.authine.cloudpivot.web.api.secondopen.controller;

import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.engine.api.facade.OrganizationFacade;
import com.authine.cloudpivot.engine.api.model.BaseModel;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentUserModel;
import com.authine.cloudpivot.engine.api.model.organization.RoleModel;
import com.authine.cloudpivot.engine.api.model.organization.RoleUserModel;
import com.authine.cloudpivot.engine.api.model.organization.UserExtAttrModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.organization.UserUnionExtAttrModel;
import com.authine.cloudpivot.engine.api.model.permission.AdminModel;
import com.authine.cloudpivot.engine.api.model.permission.DepartmentScopeModel;
import com.authine.cloudpivot.engine.api.model.permission.SelectionScopeModel;
import com.authine.cloudpivot.engine.api.model.runtime.SelectionValue;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.status.UserStatus;
import com.authine.cloudpivot.engine.enums.type.AdminType;
import com.authine.cloudpivot.engine.enums.type.CorpRelatedType;
import com.authine.cloudpivot.engine.enums.type.DeptType;
import com.authine.cloudpivot.engine.enums.type.DeptVisibleType;
import com.authine.cloudpivot.engine.enums.type.OrgType;
import com.authine.cloudpivot.engine.enums.type.StaffVisibleType;
import com.authine.cloudpivot.engine.enums.type.UnitType;
import com.authine.cloudpivot.web.api.cache.RedisCacheService;
import com.authine.cloudpivot.web.api.controller.base.PermissionController;
import com.authine.cloudpivot.web.api.controller.orgnization.SelectionHelper;
import com.authine.cloudpivot.web.api.controller.orgnization.SelectionHelperExt;
import com.authine.cloudpivot.web.api.dubbo.DubboConfigService;
import com.authine.cloudpivot.web.api.exception.PortalException;
import com.authine.cloudpivot.web.api.exception.ResultEnum;
import com.authine.cloudpivot.web.api.handler.CustomizedOrigin;
import com.authine.cloudpivot.web.api.helper.ExportCommonHelper;
import com.authine.cloudpivot.web.api.helper.FileOperateHelper;
import com.authine.cloudpivot.web.api.helper.oraganization.DeptHelper;
import com.authine.cloudpivot.web.api.task.RunTimeThreadTask;
import com.authine.cloudpivot.web.api.util.DateUtils;
import com.authine.cloudpivot.web.api.util.ReflectUtil;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.authine.cloudpivot.web.api.view.organization.DepartmentVO;
import com.authine.cloudpivot.web.api.view.organization.DeptVO;
import com.authine.cloudpivot.web.api.view.organization.ExportUser;
import com.authine.cloudpivot.web.api.view.organization.OrgRelationCheckVO;
import com.authine.cloudpivot.web.api.view.organization.UserSelectionVO;
import com.authine.cloudpivot.web.api.view.organization.UserVO;
import com.authine.cloudpivot.web.api.view.runtime.FileOperationResult;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import joptsimple.internal.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @Author: brookpeng
 * @Date: 2021/11/18 9:55
 */
@Api(tags = "组织机构::部门")
@RestController
@RequestMapping("/api/organization/department")
@Validated
@Slf4j
@CustomizedOrigin(level = 1)
public class DepartmentControllerNew extends PermissionController {

    private static final String FILE_NAME_NOT_EMPTY = "文件名称不能为空";
    @Autowired
    private RunTimeThreadTask springThreadTask;
    @Autowired
    private DubboConfigService dubboConfigService;
    @Autowired
    private RedisCacheService redisCacheService;

    @Autowired
    private SelectionHelper selectionHelper;
    @Autowired
    private SelectionHelperExt selectionHelperExt;
    private static ExecutorService executorService = Executors.newScheduledThreadPool(4);


    @GetMapping("/childs")
    @ApiOperation(value = "查询组织机构的子组织", notes = "通过 deptId 获取组织机构的子组织,deptId空则查询第一级")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", dataType = "String", paramType = "query", defaultValue = "''"),
            @ApiImplicitParam(name = "filterType", value = "过滤类型  admin(admim端组织结构过滤，主要为过滤应用管理员的查看范围)", defaultValue = "0", required = false)
    })
    public ResponseResult<List<DepartmentModel>> getChilds(@RequestParam(defaultValue = "") String deptId, @RequestParam(required = false) String filterType) {
        return getOkResponseResult(getDepartmentModelsByDeptId(deptId, filterType), "查询组织机构成功");
    }

    //查询部门id下的所有亲子部门
    private List<DepartmentModel> getDepartmentModelsByDeptId(String deptId, String filterType) {
        List<DepartmentModel> departmentList = Lists.newArrayList();
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.ASC, "sortKey"));
        orders.add(new Sort.Order(Sort.Direction.ASC, "modifiedTime"));

        Map<String, RelatedCorpSettingModel> relatedmap = new HashMap<>();
        getSystemManagementFacade().getAllRelatedCorpSettingModel().stream().forEach(related -> {
            relatedmap.put(related.getCorpId(), related);
        });

        /* start */
        List<String> ids = new ArrayList<>();
        String loginUserId = getUserId();
        ids.add(loginUserId);
        Map<String, List<RoleModel>> userRole = getOrganizationFacade().getRolesByUserIds(ids);
        boolean isAdministrator = false;
        String mainCorpId = getMainCorpId();
        UserModel admin = getOrganizationFacade().getUserByUserNameAndCorpId("admin", mainCorpId);
        String adminId = admin.getId();
        if (StringUtils.isNotEmpty(filterType) && "admin".equals(filterType) && loginUserId.equals(adminId)) {
            isAdministrator = true;
        } else {
            for (Map.Entry<String, List<RoleModel>> entry : userRole.entrySet()) {
                for (RoleModel roleModel : entry.getValue()) {
                    String roleName = roleModel.getName();
                    switch (roleName) {
                        case "集团管理人员":
                            isAdministrator = true;
                            break;
                        case "公司管理人员":
                            isAdministrator = true;
                            break;
                        default:
                            isAdministrator = false;
                    }
                    if (isAdministrator) {
                        break;
                    }
                }
                if (isAdministrator) {
                    break;
                }
            }
        }
        /* end */

        //需要根据管理员管理范围过滤
        Set<String> deptSet;
        AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
        if (StringUtils.isNotEmpty(filterType) && "admin".equals(filterType) && appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
            Set<String> deptSets = getManagePermDepartmentId(getUserId());
            //过滤掉CorpId不同的部门
            List<DepartmentScopeModel> departments = appAdminByUser.getDepartments();
            List<String> departmentsIds = departments.stream().map(DepartmentScopeModel::getUnitId).collect(Collectors.toList());
            List<DepartmentModel> departmentsByDeptIds = getOrganizationFacade().getDepartmentsByDeptIds(departmentsIds);
            Set<String> corpIds = departmentsByDeptIds.stream().map(DepartmentModel::getCorpId).collect(Collectors.toSet());
            //筛选组织是否有上级组织
            corpIds.forEach(s -> {
                //通过组织名字和corpId查询组织部门
                List<RelatedCorpSettingModel> models = getSystemManagementFacade().getAllRelatedCorpSettingModel();
                List<RelatedCorpSettingModel> relatedCorpSettingModelhaveCorp = models.stream().filter(relatedCorpSettingModel -> StringUtils.isNotBlank(relatedCorpSettingModel.getParentId())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(relatedCorpSettingModelhaveCorp)) {
                    relatedCorpSettingModelhaveCorp.forEach(relatedCorpSettingModel -> {
                        if (relatedCorpSettingModel.getCorpId().equals(s)) {
                            String corpId = getOrganizationFacade().getDepartment(relatedCorpSettingModel.getParentId()).getCorpId();
                            corpIds.add(corpId);
                        }
                    });
                }
            });
            //筛选组织下是否有其他组织
            List<RelatedCorpSettingModel> relatedCorpSettingModels = getSystemManagementFacade().getAllRelatedCorpSettingModel();
            List<RelatedCorpSettingModel> relatedCorpSettingModelList = relatedCorpSettingModels.stream().filter(relatedCorpSettingModel -> !Objects.isNull(relatedCorpSettingModel.getParentId()) && relatedCorpSettingModel.getParentId() != "").collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(relatedCorpSettingModelList)) {
                relatedCorpSettingModelList.forEach(relatedCorpSettingModel -> {
                    String corpId = getOrganizationFacade().getDepartment(relatedCorpSettingModel.getParentId()).getCorpId();
                    if (corpIds.contains(corpId)) {
                        corpIds.add(relatedCorpSettingModel.getCorpId());
                    }
                });
            }
            List<String> deptList = new ArrayList<>(deptSets);
            List<DepartmentModel> departmentModels = getOrganizationFacade().getDepartmentsByDeptIds(deptList);
            deptSet = departmentModels.stream().filter(departmentModel -> corpIds.contains(departmentModel.getCorpId())).map(DepartmentModel::getId).collect(Collectors.toSet());
            if (CollectionUtils.isEmpty(deptSet)) {
                return null;
            }
        } else {
            deptSet = new HashSet<>(2);
        }
        if (StringUtils.isEmpty(deptId)) {
            List<DepartmentModel> rootDepartments = getOrganizationFacade().getRootDepartment();
            if (CollectionUtils.isNotEmpty(rootDepartments)) {
                List<RelatedCorpSettingModel> relatedCorpSettingModels = getSystemManagementFacade().getAllRelatedCorpSettingModel();

                //挂载在当前组织下的关联组织人数算当前组织下统计
                Map<String, Set<String>> containCorpIdMaps = Maps.newHashMap();
                for (RelatedCorpSettingModel relatedCorpSettingModel : relatedCorpSettingModels) {
                    Set<String> containCorpIds;
                    String key = null;
                    if (relatedCorpSettingModel.getParentId() == null) {
                        continue;
                    }

                    DepartmentModel parent = getOrganizationFacade().getDepartment(relatedCorpSettingModel.getParentId());
                    if (parent != null && !relatedCorpSettingModel.getCorpId().equals(parent.getCorpId())) {
                        key = parent.getCorpId();
                        if (containCorpIdMaps.get(key) == null) {
                            containCorpIds = Sets.newHashSet();
                        } else {
                            containCorpIds = containCorpIdMaps.get(key);
                        }
                        containCorpIds.add(relatedCorpSettingModel.getCorpId());
                        if (StringUtils.isNotEmpty(key)) {
                            containCorpIdMaps.put(key, containCorpIds);
                        }
                    }

                }
                for (int i = 0; i < rootDepartments.size(); i++) {
                    DepartmentModel rootDepartment = rootDepartments.get(i);
                    if (CollectionUtils.isNotEmpty(deptSet) && !deptSet.contains(rootDepartment.getId())) {
                        continue;
                    }

                    Set<String> containCorpIds = containCorpIdMaps.get(rootDepartment.getCorpId());

                    Integer integer = getOrganizationFacade().countUser(rootDepartment.getCorpId());

                    if (CollectionUtils.isNotEmpty(containCorpIds)) {
                        for (String containCorpId : containCorpIds) {
                            integer += getOrganizationFacade().countUser(containCorpId);
                        }
                    }

                    rootDepartment.setEmployees(Optional.ofNullable(integer).orElse(null));
                    List<DepartmentModel> children = CollectionUtils.isNotEmpty(deptSet)
                            ? getOrganizationFacade().getDepartmentsByParentId(rootDepartment.getId(), true).stream().filter(dept -> deptSet.contains(dept.getId())).collect(Collectors.toList())
                            : getOrganizationFacade().getDepartmentsByParentId(rootDepartment.getId(), true);
                    children.stream().forEach(dept -> {
                        RelatedCorpSettingModel relatedCorpSettingModel = relatedmap.get(dept.getCorpId());
                        if (relatedCorpSettingModel != null) {
                            dept.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
                            dept.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
                        }
                    });
                    /* start */
                    List<DepartmentModel> newChildren = new ArrayList<>();
                    newChildren.addAll(children);
                    if (!isAdministrator) {
                        for (DepartmentModel child : children) {
                            String name = child.getName();
                            if ("高管层".equals(name) || "管委办".equals(name)) {
                                IntStream.range(0, newChildren.size()).filter(j->newChildren.get(j).getName().equals(name)).boxed().findFirst().map(j->newChildren.remove((int)j));
                            }
                        }
                    }
                    /* end */
                    rootDepartment.setChildren(newChildren);
                    departmentList.add(rootDepartment);
                }
            }
        } else {
            departmentList = CollectionUtils.isNotEmpty(deptSet) ? getOrganizationFacade().getDepartmentsByParentId(deptId, true).stream().filter(dept -> deptSet.contains(dept.getId())).collect(Collectors.toList())
                    : getOrganizationFacade().getDepartmentsByParentId(deptId, true);
            /*start*/
            if (!isAdministrator) {
                List<DepartmentModel> newChildren = new ArrayList<>();
                newChildren.addAll(departmentList);
                for (DepartmentModel departmentModel : departmentList) {
                    String name = departmentModel.getName();
                    if ("高管层".equals(name) || "管委办".equals(name)) {
                        IntStream.range(0, newChildren.size()).filter(j -> newChildren.get(j).getName().equals(name)).boxed().findFirst().map(j -> newChildren.remove((int) j));
                    }
                }
                departmentList.clear();
                departmentList.addAll(newChildren);
            }
            /*end*/
        }
        if (CollectionUtils.isNotEmpty(departmentList)) {
            departmentList = departmentList.stream().filter(Objects::nonNull).filter(item -> Boolean.TRUE.equals(item.getIsShow())).map(dept -> {
                RelatedCorpSettingModel relatedCorpSettingModel = relatedmap.get(dept.getCorpId());
                if (relatedCorpSettingModel != null) {
                    dept.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
                    dept.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
                }
                return dept;
            }).collect(Collectors.toList());
        }
        return departmentList;
    }

    @ApiOperation(value = "查询组织机构的子组织,树形控件", notes = "通过 deptIds 获取组织机构的子组织多个用','隔开，不查询第一级部门下的子部门,deptIds空则查询第一级")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptIds", value = "部门ids", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "filterType", value = "过滤类型，可选：admin admin_corp(应用管理员相关) related main  self(只显示自维护的部门) root_display(直接返回deptIds指定的部门)", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "corpId", value = "corpId", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sourceType", value = "来源类型，admin-后台，portal-门户", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "excludeCorpId", value = "要过滤的企业id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "selectUserIds", value = "选人控件中选中的用户id集合，逗号隔开，用来过滤其所在部门和兼职部门及其下子部门，和当前查询的应用管理员权限取交集", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "formRootDeptIds", value = "表单根部门id", dataType = "String", paramType = "query")
    })
    @GetMapping("/tree")
    public ResponseResult<Map<String, List<DepartmentModel>>> tree(@RequestParam(defaultValue = "") String deptIds, @RequestParam(required = false) String filterType, @RequestParam(required = false) String corpId,
                                                                   @RequestParam(required = false) String sourceType, @RequestParam(required = false) String excludeCorpId, String selectUserIds, @RequestParam(required = false) String formRootDeptIds) {
        long start = System.currentTimeMillis();
        long begin = System.currentTimeMillis();
        final String requestFrom = sourceType;
        //参数优先级调整
        List<String> deptIdParams = null;
        if (StringUtils.isNotEmpty(deptIds)) {
            deptIdParams = Splitter.on(",").splitToList(deptIds);
            sourceType = null;
        }
        String userId = getUserId();
        log.info("用户id：userId={}", JSON.toJSONString(userId));

        if ("self".equals(filterType)) {
            return getOkResponseResult(selectionHelper.selectionTreeHandler2(deptIds, filterType, corpId, getUserId()), "查询树形组织机构成功");
        } else if ("root_display".equals(filterType) && StringUtils.isNotEmpty(deptIds)) {
            Map<String, List<DepartmentModel>> display = selectionHelper.selectionTreeHandler2RootDisplay(deptIds);
            display.forEach((key, list) -> display.put(key, selectionHelper.filterDeptTree(list, formRootDeptIds, requestFrom)));
            UserModel user = getOrganizationFacade().getUser(userId);
            Map<String, List<DepartmentModel>> myDepartment = getMyDepartment(user.getCorpId(), user);
            List<DepartmentModel> models = display.get("departmentList");
            Map<String, List<DepartmentModel>> finalData = selectionHelper.getMyDepartment(models, user, requestFrom, myDepartment);
            finalData.putAll(display);
            return getOkResponseResult(finalData, "查询树形组织机构成功");
        }
        long end = System.currentTimeMillis();
        log.info("process time1:{}", end - begin);
        begin = end;
        List<DepartmentModel> departmentList = new ArrayList<>();

        Map<String, List<DepartmentModel>> result = Maps.newHashMap();

        String mainOrgType = null;
        String excludedeptid = null;//要排除的部门
        if (StringUtils.isNotEmpty(corpId) && "MAIN_ORG".equals(corpId)) {
            corpId = null;
            mainOrgType = OrgType.MAIN.getName();
        } else if (StringUtils.isNotEmpty(corpId) && corpId.split("@@").length == 2) {
            if (corpId.split("@@")[1].startsWith("excludedeptid")) {
                excludedeptid = corpId.split("@@")[1].replace("excludedeptid-", "");
            }
            corpId = corpId.split("@@")[0];
        }

        //判断是否应用管理员
        AdminModel appAdminByUser = getAppAdminByUserId(userId);
        SelectionHelper.SelectionFilter filterInfo = selectionHelper.relatedSelection(deptIds, filterType, corpId, appAdminByUser);
        final boolean finalNeedFilterCorp = filterInfo.isNeedFilterCorp();
        final boolean needFilter = filterInfo.isNeedFilterAppAdmin();
        final String finalCorpId = filterInfo.getCorpId();
        Set<String> allPathDeptSet;
        boolean isFirst = StringUtils.isEmpty(deptIds);
        //当前登录用户组织范围和选择的用户所属部门及其子部门交集
        Set<String> loginUserDeptPermAndSelectUsersMixed = null;
        if (filterInfo.isNeedFilterAppAdmin() && appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
            allPathDeptSet = getManagePermChildDepartmentId(userId);
            if (CollectionUtils.isEmpty(allPathDeptSet)) {
                result.put("departmentList", null);
                return getOkResponseResult(result, "查询树形组织机构成功");
            }

            if (StringUtils.isNotEmpty(selectUserIds)) {
                loginUserDeptPermAndSelectUsersMixed = getLoginUserDeptPermAndSelectUsersMixed(allPathDeptSet, selectUserIds);
                deptIds = StringUtils.join(getParentDeptIdsByMixed(loginUserDeptPermAndSelectUsersMixed), ",");
            } else if (isFirst) {
                Set<String> parentDeptIds = getParentDeptIds(appAdminByUser);
                //如果是应用管理员首次查询且需要corpId过滤且直接管理部门里没有该corpId的部门  就获取corpId的跟部门 判断在不在管理范围（子部门）内
                if (needFilter && parentDeptIds.size() > 0
                        && !getOrganizationFacade().getDepartmentsByDeptIds(new ArrayList<>(parentDeptIds)).stream().
                        filter(dept -> StringUtils.isNotEmpty(finalCorpId) ? finalCorpId.equals(dept.getCorpId()) : true).findAny().isPresent()) {
                    ;
                    DepartmentModel rootDepartmentByCorpId = getOrganizationFacade().getRootDepartmentByCorpId(finalCorpId);
                    if (allPathDeptSet.contains(rootDepartmentByCorpId.getId())) {
                        parentDeptIds.add(rootDepartmentByCorpId.getId());
                    }
                }
                deptIds = StringUtils.join(parentDeptIds, ",");
            }

        } else {
            allPathDeptSet = new HashSet<>(2);
        }
        end = System.currentTimeMillis();
        log.info("process time2:{}", end - begin);
        begin = end;

        //家校通需求：
        if (CollectionUtils.isEmpty(getPermissionManagementFacade().getAdminByUserId(userId))) {
            //家长跟学生不是挂在班级下，而是加在部门 学生/家长下
            List<DepartmentModel> depts = getOrganizationFacade().getDepartmentsByUserId(userId);
            boolean isEDU = depts.stream().filter(dept -> DeptType.EDU_DEPT.equals(dept.getDeptType()))
                    .findAny().orElse(null) != null ? true : false;
            if (isEDU && StringUtils.isEmpty(deptIds)) {
                deptIds = StringUtils.join(depts.stream().map(DepartmentModel::getParentId).collect(Collectors.toSet()), ",");
            }
        }
        if (StringUtils.isEmpty(deptIds) && StringUtils.isNotEmpty(selectUserIds)) {
            //TAPD需求ID：1005979 当表单未设置跟部门(即入参deptIds为空时)，需要根据编辑部门设置进行过滤
            result.put("departmentList", selectionHelper.filterDeptTree(departmentList, formRootDeptIds, requestFrom));
            return getOkResponseResult(result, "查询树形组织机构成功");
        }

        //查询条件deptId与当前用户的管理范围取交集
        if (CollectionUtils.isNotEmpty(deptIdParams) && StringUtils.isNotEmpty(deptIds)) {
            List<String> departIdList = Splitter.on(",").splitToList(deptIds);
            List<String> tempIdList = Lists.newArrayList();
            for (String id : departIdList) {
                if (deptIdParams.contains(id)) {
                    tempIdList.add(id);
                }
            }
            deptIds = StringUtils.join(tempIdList, ",");
        }
        end = System.currentTimeMillis();
        log.info("process time3:{}", end - begin);
        begin = end;

        if (StringUtils.isEmpty(deptIds)) {
            //获取本部门
            UserModel user = null;
            user = getOrganizationFacade().getUser(userId);

            log.info("用户：user={}", JSON.toJSONString(user));
            departmentList = getRootDepartmentModels(user.getCorpId(), sourceType)
                    .stream().filter(dept -> finalNeedFilterCorp && StringUtils.isNotEmpty(finalCorpId) ? finalCorpId.equals(dept.getCorpId()) : true).collect(Collectors.toList());

            //对于要排除的部门处理
            if (StringUtils.isNotEmpty(excludedeptid)) {
                final String excludedeptid_temp = excludedeptid;
                departmentList = departmentList.stream().filter(dept -> !excludedeptid_temp.equals(dept.getId())).collect(Collectors.toList());
            }

            //若需要过滤关联部门且关联部门非根部门，需要把关联组织跟部门作为跟部门显示
            if (CollectionUtils.isEmpty(departmentList)) {
                DepartmentModel corpRootDept = getOrganizationFacade().getRootDepartmentByCorpId(finalCorpId);
                if (Objects.nonNull(corpRootDept)) {
                    if (corpRootDept.isLeaf()) {
                        List<UserModel> userModels = getOrganizationFacade().getUsersByDeptId(corpRootDept.getId());
                        corpRootDept.setEmployees(CollectionUtils.isEmpty(userModels) ? 0 : userModels.size());
                    }
                    departmentList.add(corpRootDept);
                }
            }

            //TAPD需求ID：1005979 当表单未设置跟部门(即入参deptIds为空时)，需要根据编辑部门设置进行过滤
            List<DepartmentModel> deptByScope = selectionHelper.filterDeptTree(departmentList, formRootDeptIds, requestFrom);
            departmentList.clear();
            departmentList.addAll(deptByScope);
            Map<String, List<DepartmentModel>> oldMyDept = getMyDepartment(finalCorpId, user);
            Map<String, List<DepartmentModel>> myDepartment = selectionHelper.getMyDepartment(deptByScope, user, requestFrom, oldMyDept);
            result.putAll(myDepartment);
            end = System.currentTimeMillis();
            log.info("process time4:{}", end - begin);
            begin = end;
        } else {
            String[] departIdList = deptIds.split(",");
            //StringUtils.isNotEmpty(selectUserIds) 判断兼容应用管理员选择组织范围
            if (departIdList.length == 1 && !isFirst) {
                if (needFilter) {
                    departmentList = getOrganizationFacade().getDepartmentsByParentId(departIdList[0], true).stream().filter(dept -> !finalNeedFilterCorp ? true : finalCorpId.equals(dept.getCorpId()) && allPathDeptSet.contains(dept.getId())).collect(Collectors.toList());
                } else {
                    departmentList = getOrganizationFacade().getDepartmentsByParentId(departIdList[0], true).stream().filter(dept -> !finalNeedFilterCorp ? true : finalCorpId.equals(dept.getCorpId()) && Boolean.TRUE.equals(dept.getIsShow())).collect(Collectors.toList());
                }
                departmentList = departmentList.stream().filter(item -> Boolean.TRUE.equals(item.getIsShow())).collect(Collectors.toList());
//                if (CollectionUtils.isNotEmpty(departmentList)) {
//                    List<String> deptIdlList = departmentList.stream().filter(DepartmentModel::isLeaf).map(DepartmentModel::getId).collect(Collectors.toList());
//                    List<UserModel> userList = getOrganizationFacade().getUsersByDeptIds(deptIdlList);
//                    if(CollectionUtils.isNotEmpty(userList)){
//                        Map<String, List<UserModel>> map = userList.stream().collect(Collectors.groupingBy(UserModel::getDepartmentId));
//                        departmentList.forEach(item->{
//                            if(!item.isLeaf()){
//                                return;
//                            }
//                            List<UserModel> tempList = map.get(item.getId());
//                            item.setEmployees(CollectionUtils.isEmpty(tempList) ? 0 : tempList.size());
//                        });
//                    }
//                }
                end = System.currentTimeMillis();
                log.info("process time5:{}", end - begin);
                begin = end;
                //对于要排除的企业处理
                if (StringUtils.isNotEmpty(excludeCorpId)) {
                    final String excludeCorpId_temp = excludeCorpId;
                    departmentList = departmentList.stream().filter(dept -> !excludeCorpId_temp.equals(dept.getCorpId())).collect(Collectors.toList());
                }
                //只查询主组织下的数据
                if (StringUtils.isNotEmpty(mainOrgType)) {
                    RelatedCorpSettingModel mainRelatedCorpSettingModel = getSystemManagementFacade().getAllRelatedCorpSettingModelByOrgType(OrgType.MAIN).get(0);
                    departmentList = departmentList.stream().filter(dept -> mainRelatedCorpSettingModel.getCorpId().equals(dept.getCorpId())).collect(Collectors.toList());
                }
                //对于要排除的部门处理
                if (StringUtils.isNotEmpty(excludedeptid)) {
                    final String excludedeptid_temp = excludedeptid;
                    departmentList = departmentList.stream().filter(dept -> !excludedeptid_temp.equals(dept.getId())).collect(Collectors.toList());
                }

                result.put("departmentList", selectionHelper.filterDeptTree(departmentList, formRootDeptIds, requestFrom));
                end = System.currentTimeMillis();
                log.info("process time6:{}", end - begin);
                log.info("process time total:{}", end - start);
                return getOkResponseResult(result, "查询树形组织机构成功");
            }

            for (String depart : departIdList) {
                if (needFilter && !allPathDeptSet.contains(depart)) {
                    continue;
                }

                DepartmentModel department = getOrganizationFacade().getDepartment(depart, true);
                if (department == null || !Boolean.TRUE.equals(department.getIsShow())) {
                    continue;
                }
                if (department.isLeaf()) {
                    List<UserModel> userModels = getOrganizationFacade().getUsersByDeptId(department.getId());
                    department.setEmployees(CollectionUtils.isEmpty(userModels) ? 0 : userModels.size());
                }
                departmentList.add(department);
            }
            List<DepartmentModel> deptByScope = selectionHelper.filterDeptTree(departmentList, formRootDeptIds, requestFrom);
            departmentList.clear();
            departmentList.addAll(deptByScope);
        }
        end = System.currentTimeMillis();
        log.info("process time7:{}", end - begin);
        begin = end;
        if (CollectionUtils.isNotEmpty(departmentList)) {

            departmentList = departmentList.stream().filter(item -> Boolean.TRUE.equals(item.getIsShow()) && Boolean.TRUE.equals(item.getEnabled())).collect(Collectors.toList());

            departmentList = departmentList.stream().filter(item -> !finalNeedFilterCorp || finalCorpId.equals(item.getCorpId())).collect(Collectors.toList());

            //对于要排除的企业处理
            if (StringUtils.isNotEmpty(excludeCorpId)) {
                final String excludeCorpId_temp = excludeCorpId;
                departmentList = departmentList.stream().filter(dept -> !excludeCorpId_temp.equals(dept.getCorpId())).collect(Collectors.toList());
            }
            //只查询主组织下的数据
            if (StringUtils.isNotEmpty(mainOrgType)) {
                RelatedCorpSettingModel mainRelatedCorpSettingModel = getSystemManagementFacade().getAllRelatedCorpSettingModelByOrgType(OrgType.MAIN).get(0);
                departmentList = departmentList.stream().filter(dept -> mainRelatedCorpSettingModel.getCorpId().equals(dept.getCorpId())).collect(Collectors.toList());
            }
            //对于要排除的部门处理
            if (StringUtils.isNotEmpty(excludedeptid)) {
                final String excludedeptid_temp = excludedeptid;
                departmentList = departmentList.stream().filter(dept -> !excludedeptid_temp.equals(dept.getId())).collect(Collectors.toList());
            }
        }
        end = System.currentTimeMillis();
        log.info("process time8:{}", end - begin);
        log.info("process time total:{}", end - start);
        result.put("departmentList", departmentList);
        return getOkResponseResult(result, "查询树形组织机构成功");
    }

    private Map<String, List<DepartmentModel>> getMyDepartment(String finalCorpId, UserModel user) {
        Map<String, List<DepartmentModel>> result = new HashMap<>();
        DepartmentModel department = getOrganizationFacade().getDepartment(user.getDepartmentId());

        log.info("我的部门数据：department={}", JSON.toJSONString(department));

        if (Objects.nonNull(department) && department.isLeaf()) {
            List<UserModel> userModels = getOrganizationFacade().getUsersByDeptId(department.getId());
            department.setEmployees(CollectionUtils.isEmpty(userModels) ? 0 : userModels.size());
        }
        //洪光提出将我的部门用真实部门显示
        Optional.ofNullable(department).ifPresent(departmentModel -> departmentModel.setName(department.getName()));
        if (StringUtils.isNotEmpty(finalCorpId) && department != null && !finalCorpId.equals(department.getCorpId())) {
            result.put("myDepartment", null);
        } else {
            result.put("myDepartment", Optional.ofNullable(department).map(ImmutableList::of).orElse(null));
        }
        return result;
    }

    private Set<String> getParentDeptIdsByMixed(Set<String> loginUserDeptPermAndSelectUsersMixed) {
        if (CollectionUtils.isEmpty(loginUserDeptPermAndSelectUsersMixed)) {
            return null;
        }
        List<DepartmentModel> mixed = new ArrayList<>();
        //查找交集的父节点
        for (String deptId : loginUserDeptPermAndSelectUsersMixed) {
            DepartmentModel department = getOrganizationFacade().getDepartment(deptId);
            mixed.add(department);
        }
        Iterator<DepartmentModel> iterator = mixed.iterator();
        while (iterator.hasNext()) {
            DepartmentModel departmentModel = iterator.next();
            if (StringUtils.isNotEmpty(departmentModel.getParentId()) && loginUserDeptPermAndSelectUsersMixed.contains(departmentModel.getParentId())) {
                iterator.remove();
            }
        }
        Set<String> collect = mixed.stream().map(DepartmentModel::getId).collect(Collectors.toSet());
        return collect;
    }

    private Set<String> getLoginUserDeptPermAndSelectUsersMixed(Set<String> allPathDeptSet, String selectUserIds) {
        if (StringUtils.isBlank(selectUserIds)) {
            return null;
        }
        String[] split = selectUserIds.split(",");
        //用户的主部门和兼职部门
        List<DepartmentUserModel> departmentUserModels = new ArrayList<>();
        for (String userId : split) {
            //获得用户的主部门和兼职部门
            departmentUserModels.addAll(getOrganizationFacade().getDepartmentUsersByUserId(userId));
        }
        List<String> collect = departmentUserModels.stream().map(departmentUserModel -> departmentUserModel.getDeptId()).collect(Collectors.toList());
        Set<String> deptChildIdSet = getOrganizationFacade().getDepartmentsChildList(collect, false)
                .stream().map(DepartmentModel::getId).collect(Collectors.toSet());
        //取交集
        deptChildIdSet.retainAll(allPathDeptSet);
        return deptChildIdSet;
    }

    //获取根部门集合，包括关联组织
    private List<DepartmentModel> getRootDepartmentModels(String corpId, String sourceType) {

        List<DepartmentModel> rootDepartments = null;
        if (StringUtils.isEmpty(corpId)) {
            rootDepartments = getOrganizationFacade().getRootDepartment();
        } else {
            if (StringUtils.isNotEmpty(sourceType)) {//根据企业类型判断
                RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(corpId);
                switch (relatedCorpSettingModel.getOrgType()) {
                    case MAIN:
                        //主组织
                        rootDepartments = getOrganizationFacade().getRootDepartment();
                        break;
                    case RELEVANCE:
                        //关联组织
                        if (rootDepartments == null) {
                            rootDepartments = Lists.newArrayList();
                        }
                        rootDepartments.clear();
                        DepartmentModel relatedCorpRootDept = getOrganizationFacade().getRootDepartmentByCorpId(corpId);
                        rootDepartments.add(relatedCorpRootDept);
                        break;
                }
            } else {
                rootDepartments = getOrganizationFacade().getRootDepartment();
            }
        }

        if (CollectionUtils.isNotEmpty(rootDepartments)) {
            initRootDepartmentModels(rootDepartments);
        }

        return rootDepartments;
    }

    private void initRootDepartmentModels(List<DepartmentModel> rootDepartments) {
        for (DepartmentModel rootDepartment : rootDepartments) {
            if (Objects.nonNull(rootDepartment) && rootDepartment.isLeaf()) {
                List<UserModel> userModels = getOrganizationFacade().getUsersByDeptId(rootDepartment.getId());
                rootDepartment.setEmployees(CollectionUtils.isEmpty(userModels) ? 0 : userModels.size());
            }
        }
    }

    @ApiOperation(value = "查询组织机构的子组织,树形控件", notes = "通过 deptId 获取组织机构，不查询第一级部门下的子部门,deptId空则查询第一级")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", dataType = "String", paramType = "query")
    })
    @GetMapping("/ext/tree")
    public ResponseResult<Map<String, List<DepartmentModel>>> treeExt(@RequestParam(defaultValue = "") String deptId) {
        return getOkResponseResult(selectionHelperExt.filterDeptTree(deptId), "查询树形组织机构成功");
    }

    @ApiOperation(value = "查询组织机构的子组织,树形控件", notes = "通过 deptIds 获取组织机构用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", dataType = "String", paramType = "query")
    })
    @GetMapping("/ext/listUser")
    public ResponseResult<List<UserSelectionVO>> listUserExt(@RequestParam String deptId) {
        validateNotEmpty(deptId, "部门ID不能为空");
        return getOkResponseResult(selectionHelperExt.filterDeptUsers(deptId), "查询部门用户成功");
    }

    @ApiOperation(value = "查询组织根部门", notes = "传入企业corpId，查询企业根节点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "corpId", value = "企业id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "filterType", value = "过滤类型  admin(admim端组织结构过滤，主要为过滤应用管理员的查看范围)", dataType = "String", paramType = "query")
    })
    @GetMapping("/get_corp_root_dept_info")
    public ResponseResult getCorpRootDeptInfo(@RequestParam String corpId, @RequestParam(required = false) String filterType) {

        //查找根节点企业
        DepartmentModel relatedCorpRootDept = getOrganizationFacade().getRootDepartmentByCorpId(corpId);
        if (relatedCorpRootDept == null) {
            return getErrResponseResult(ErrCode.UNKNOW_ERROR.getErrCode(), "根部门节点为空");
        }
        while (StringUtils.isNotEmpty(relatedCorpRootDept.getParentId())) {
            relatedCorpRootDept = getOrganizationFacade().getDepartment(relatedCorpRootDept.getParentId());
            relatedCorpRootDept = getOrganizationFacade().getRootDepartmentByCorpId(relatedCorpRootDept.getCorpId());
        }

        /********************数据准备**********************/
        List<DepartmentModel> rootDepartments = getOrganizationFacade().getRootDepartment();
        List<RelatedCorpSettingModel> relatedCorpSettingModels = getSystemManagementFacade().getAllRelatedCorpSettingModel();

        //挂载在当前组织下的关联组织人数算当前组织下统计
        Map<String, Set<String>> containCorpIdMaps = Maps.newHashMap();
        for (RelatedCorpSettingModel relatedCorpSettingModel : relatedCorpSettingModels) {
            Set<String> containCorpIds;
            String key = null;
            if (relatedCorpSettingModel.getParentId() == null) {
                continue;
            }

            DepartmentModel parent = getOrganizationFacade().getDepartment(relatedCorpSettingModel.getParentId());
            if (parent != null && !relatedCorpSettingModel.getCorpId().equals(parent.getCorpId())) {
                key = parent.getCorpId();
                if (containCorpIdMaps.get(key) == null) {
                    containCorpIds = Sets.newHashSet();
                } else {
                    containCorpIds = containCorpIdMaps.get(key);
                }
                containCorpIds.add(relatedCorpSettingModel.getCorpId());
                if (StringUtils.isNotEmpty(key)) {
                    containCorpIdMaps.put(key, containCorpIds);
                }
            }

        }
        //需要根据管理员管理范围过滤
        Set<String> deptSet;
        AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
        if (StringUtils.isNotEmpty(filterType) && "admin".equals(filterType) && appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
            deptSet = getManagePermDepartmentId(getUserId());
            if (CollectionUtils.isEmpty(deptSet)) {
                return null;
            }
        } else {
            deptSet = new HashSet<>(2);
        }
        for (int i = 0; i < rootDepartments.size(); i++) {
            DepartmentModel rootDepartment = rootDepartments.get(i);
            if (CollectionUtils.isNotEmpty(deptSet) && !deptSet.contains(rootDepartment.getId())) {
                continue;
            }

            Set<String> containCorpIds = containCorpIdMaps.get(rootDepartment.getCorpId());

            Integer integer = getOrganizationFacade().countUser(rootDepartment.getCorpId());

            if (CollectionUtils.isNotEmpty(containCorpIds)) {
                for (String containCorpId : containCorpIds) {
                    integer += getOrganizationFacade().countUser(containCorpId);
                }
            }

            if (relatedCorpRootDept.getId().equals(rootDepartment.getId())) {
                relatedCorpRootDept.setEmployees(Optional.ofNullable(integer).orElse(null));
            }
        }

        return getOkResponseResult(relatedCorpRootDept, "获取组织机构的用户成功");
    }

    @ApiOperation(value = "查询直接隶属于该组织的用户", notes = "传入组织机构 deptId，获取直接隶属于该组织的用户，传空则获取我的公司下的用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "Integer", paramType = "query", defaultValue = "0"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "100")
    })
    @GetMapping("/users")
    public ResponseResult<Page<UserVO>> users(@RequestParam String deptId, Integer page, Integer size, @RequestParam(required = false) String filterType) {
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(Sort.Order.desc("leader"));
        orders.add(Sort.Order.desc("sortKey"));
        Sort sort = new Sort(orders);
        Pageable pageable = PageRequest.of(page == null ? 0 : page, size == null ? 100 : size, sort);
        Page<UserModel> userPage;
        List<UserVO> userVOList;
        List<UserModel> userList;

        //应用管理员判断
        if (StringUtils.isNotEmpty(filterType) && "admin".equals(filterType)) {
            AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
            if (appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
                Set<String> childDeptSet = getManagePermChildDepartmentId(getUserId());
                if (!childDeptSet.contains(deptId)) {
                    Page<UserVO> userVOPage = new PageImpl<>(Lists.newArrayList(), pageable, 0);
                    return getOkResponseResult(userVOPage, "获取组织机构的用户成功");
                }
            }
        }
        DepartmentModel departmentInfo = null;
        if (StringUtils.isEmpty(deptId)) {
            List<DepartmentModel> rootDepartments = getOrganizationFacade().getRootDepartment();
            //如果部门为空
            if (CollectionUtils.isEmpty(rootDepartments)) {
                userPage = Page.empty(pageable);
                userVOList = Lists.newArrayList();
                //部门非空
            } else {
                departmentInfo = rootDepartments.get(0);
                deptId = rootDepartments.get(0).getId();
                userPage = getOrganizationFacade().getUsersByDeptId(rootDepartments.get(0).getId(), pageable);
                userList = userPage.getContent();
                userList = userList.stream().filter(userModel -> UserStatus.ENABLE == userModel.getStatus()).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(userList)) {
                    Page<UserVO> userVOPage = new PageImpl<>(Lists.newArrayList(), pageable, 0);
                    return getOkResponseResult(userVOPage, "获取组织机构的用户成功");
                }
                for (UserModel userModel : userList) {
                    if (null != userModel) {
                        String id = userModel.getId();
                        DepartmentUserModel deptUser = getOrganizationFacade().getDepartmentUserByDeptIdAndUserId(deptId, id);
                        log.info("用户部门" + deptUser);
                        userModel.setSortKey(deptUser.getSortKey());
                        if (departmentInfo != null && StringUtils.isNotEmpty(departmentInfo.getManagerId())) {
                            userModel.setLeader(departmentInfo.getManagerId().equals(userModel.getUserId()));
                        } else {
                            userModel.setLeader(deptUser.getLeader());
                        }
                    }
                }
                //加入开关区分 用户
                userVOList = getUserVOList(userList);
                //加入是否管理员字段
//                setManager(rootDepartments.get(0).getId(), userVOList);
                sortByManager(userVOList);
            }
        } else {
            departmentInfo = getOrganizationFacade().getDepartment(deptId);
            userPage = getOrganizationFacade().getUsersByDeptId(deptId, pageable);
            userList = userPage.getContent();
            userList = userList.stream().filter(userModel -> UserStatus.ENABLE == userModel.getStatus()).collect(Collectors.toList());
            List<UserModel> users = new ArrayList<>();
            if (CollectionUtils.isEmpty(userList)) {
                Page<UserVO> userVOPage = new PageImpl<>(Lists.newArrayList(), pageable, 0);
                return getOkResponseResult(userVOPage, "获取组织机构的用户成功");
            }

            for (UserModel userModel : userList) {
                if (null != userModel) {
                    String id = userModel.getId();
                    DepartmentUserModel deptUser = getOrganizationFacade().getDepartmentUserByDeptIdAndUserId(deptId, id);
                    log.info("用户部门" + deptUser);
                    userModel.setSortKey(deptUser.getSortKey());
                    /*if (departmentInfo != null && StringUtils.isNotEmpty(departmentInfo.getManagerId())) {
                        userModel.setLeader(departmentInfo.getManagerId().equals(userModel.getUserId()));
                    } else {
                        userModel.setLeader(deptUser.getLeader());
                    }*/

                    users.add(userModel);
                }
            }
            userVOList = getUserVOList(userList);
            //加入是否管理员字段
//                setManager(deptId, userVOList);
            sortByManager(userVOList);
        }

        //添加所属角色字段
        setRoleName(userVOList);

        if (CollectionUtils.isNotEmpty(userVOList)) {
            Map<String, RelatedCorpSettingModel> relatedmap = new HashMap<>();
            getSystemManagementFacade().getAllRelatedCorpSettingModel().stream().forEach(related -> {
                relatedmap.put(related.getCorpId(), related);
            });
            String finalDeptId = deptId;
            userVOList.stream().filter(Objects::nonNull).forEach(item -> {
                if (StringUtils.isNotEmpty(item.getCorpId())) {
                    RelatedCorpSettingModel corpSettingModel = relatedmap.get(item.getCorpId());
                    if (corpSettingModel != null) {
                        item.setRelatedOrgType(corpSettingModel.getOrgType());
                        item.setRelatedSyncType(corpSettingModel.getSyncType());
                    } else {//兼容处理，因为导入未考虑到多组织的情况，所以用户数据corpId为空
                        if (StringUtils.isNotEmpty(finalDeptId)) {
                            DepartmentModel dept = getOrganizationFacade().getDepartment(finalDeptId);
                            RelatedCorpSettingModel relatedCorpSetting = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(dept.getCorpId());
                            item.setRelatedOrgType(relatedCorpSetting.getOrgType());
                            item.setRelatedSyncType(relatedCorpSetting.getSyncType());
                        }
                    }
                }
            });
        }

        if (getOrganizationFacade().getLicensePermGateway()) {
            if (CollectionUtils.isNotEmpty(userVOList)) {
                List<String> userIds = userVOList.stream().filter(Objects::nonNull).map(BaseModel::getId).collect(Collectors.toList());
                Map<String, Boolean> userMaps = getOrganizationFacade().getLicensePermUsersByUserIds(userIds);
                userVOList.forEach(item -> {
                    item.setIsAuthUser(userMaps.get(item.getId()));
                });
            }
        }

        Page<UserVO> userVOPage = new PageImpl<>(userVOList, pageable, userPage.getTotalElements());
        log.info("用户列表" + userVOPage);
        return getOkResponseResult(userVOPage, "获取组织机构的用户成功");
    }

    @ApiOperation(value = "查询直接隶属于该组织的用户", notes = "传入组织机构 deptId，获取直接隶属于该组织的用户，传空则获取我的公司下的用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "roleId", value = "角色id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "filterType", value = "过滤类型", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sourceType", value = "来源类型，admin-后台，portal-门户", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "workflowInstanceId", value = "流程id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "activityCode", value = "活动code", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "formRootDeptIds", value = "表单跟部门id", dataType = "String", paramType = "query")
    })
    @GetMapping("/list_user")
    public ResponseResult<List<UserSelectionVO>> listUsers(@RequestParam String deptId, @RequestParam(required = false) String roleId,
                                                           @RequestParam(required = false) String filterType,
                                                           @RequestParam(required = false) String sourceType,
                                                           String workflowInstanceId, String activityCode,
                                                           @RequestParam(required = false) String formRootDeptIds) {
        validateNotEmpty(deptId, "部门id不能为空");
        DepartmentModel department = getOrganizationFacade().getDepartment(deptId);
        List<UserSelectionVO> userSelectionVOS = Lists.newArrayList();

        if (StringUtils.isNotEmpty(filterType) && "admin".equals(filterType)) {
            AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
            if (appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
                Set<String> childDeptSet = getManagePermChildDepartmentId(getUserId());
                if (!childDeptSet.contains(deptId)) {
                    return getOkResponseResult(userSelectionVOS, "获取用户成功");
                }
            }
        }

        if (Strings.isNullOrEmpty(roleId)) {
            List<UserModel> userModels = getOrganizationFacade().getUsersByDeptId(deptId);
            if (CollectionUtils.isNotEmpty(userModels)) {
                RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(department.getCorpId());
                for (UserModel userModel : userModels) {
                    UserSelectionVO userSelectionVO = new UserSelectionVO();
                    BeanUtils.copyProperties(userModel, userSelectionVO);
                    List<DepartmentModel> departmentsByUserId = getOrganizationFacade().getDepartmentsByUserId(userModel.getId());
                    List<SelectionValue> departments = Lists.newArrayList();
                    for (DepartmentModel dep : departmentsByUserId) {
                        if (!dep.getIsShow()) {
                            continue;
                        }
                        SelectionValue selectionValue = new SelectionValue();
                        selectionValue.setId(dep.getId());
                        selectionValue.setName(dep.getName());
                        selectionValue.setType(UnitType.DEPARTMENT);
                        departments.add(selectionValue);
                    }
                    DepartmentUserModel deptUser = getOrganizationFacade().getDepartmentUserByDeptIdAndUserId(deptId, userModel.getId());
                    log.info("用户部门" + deptUser);
                    userSelectionVO.setSortKey(deptUser.getSortKey());
                    userSelectionVO.setDepartments(departments);
                    userSelectionVO.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
                    userSelectionVO.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
                    Map<String, Object> propertiesMap = new HashMap<String, Object>();
                    List<UserUnionExtAttrModel> userUnionList = dubboConfigService.getUserExtendFacade().getUnionExtAttrsByUserId(userModel.getId());
                    userUnionList.forEach(userUnion -> {
                        UserExtAttrModel userExtAttrModel = dubboConfigService.getUserExtendFacade().getUserExtendByExtendAttrId(userUnion.getExtendAttrId());
                        if (userExtAttrModel != null) {
                            propertiesMap.put(userExtAttrModel.getCode(), userUnion.getMapVal());
                        }
                    });
                    Object obj = ReflectUtil.getObject(userSelectionVO, propertiesMap);
                    userSelectionVOS.add((UserSelectionVO) obj);
                }
            }
            sort(userSelectionVOS);
        } else {
            List<UserModel> userModels = getOrganizationFacade().getUsersByDeptIdAndRoleId(deptId, roleId);
            if (CollectionUtils.isNotEmpty(userModels)) {
                RoleModel role = getOrganizationFacade().getRole(roleId);
                String roleName = Optional.ofNullable(role).map(RoleModel::getName).orElse(null);

                RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(role.getCorpId());

                for (UserModel userModel : userModels) {
                    UserSelectionVO userSelectionVO = new UserSelectionVO();
                    BeanUtils.copyProperties(userModel, userSelectionVO);
                    List<DepartmentModel> departmentsByUserId = getOrganizationFacade().getDepartmentsByUserId(userModel.getId());
                    List<SelectionValue> departments = Lists.newArrayList();
                    for (DepartmentModel dep : departmentsByUserId) {
                        if (!dep.getIsShow()) {
                            continue;
                        }
                        SelectionValue selectionValue = new SelectionValue();
                        selectionValue.setId(dep.getId());
                        selectionValue.setName(dep.getName());
                        selectionValue.setType(UnitType.DEPARTMENT);
                        departments.add(selectionValue);
                    }
                    userSelectionVO.setDepartments(departments);
                    userSelectionVO.setRoleName(roleName);
                    userSelectionVO.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
                    userSelectionVO.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
                    userSelectionVOS.add(userSelectionVO);
                }
            }
        }
        if (!StringUtils.isBlank(sourceType)) {
            filterUserByOrgType(userSelectionVOS);
        }
        if (CollectionUtils.isNotEmpty(userSelectionVOS)) {
            for (UserSelectionVO selectionVO : userSelectionVOS) {
                setRoleName(selectionVO.getId(), selectionVO);
            }
        }

        if (StringUtils.isNotEmpty(workflowInstanceId) && StringUtils.isNotEmpty(activityCode)) {
            //所有流程参与者
            Set<String> participants = getWorkflowInstanceFacade().getParticipants(workflowInstanceId, activityCode);
            removeParticipants(userSelectionVOS, participants);
        }

        List<UserSelectionVO> vos = selectionHelper.filterListUser(userSelectionVOS, deptId, formRootDeptIds, sourceType);
        return getOkResponseResult(vos, "获取用户成功");
    }

    /**
     * 给用户排序
     *
     * @param userSelectionVOS
     */
    private void sort(List<UserSelectionVO> userSelectionVOS) {
        if (CollectionUtils.isEmpty(userSelectionVOS)) {
            return;
        }
        //发现不能对两个字段进行排序
        userSelectionVOS.sort((o1, o2) -> {
            if (o1.getSortKey() == null && o2.getSortKey() == null) {
                return 0;
            }
            if (o1.getSortKey() == null) {
//                return -o2.getSortKey().intValue();
                return -1;
            }
            if (o2.getSortKey() == null) {
//                return o1.getSortKey().intValue();
                return 1;
            }
//            int i = (int) (o1.getSortKey().longValue() - o2.getSortKey().longValue());
//            return i>0?1:(i<0?-1:0);
            return o2.getSortKey().toString().compareTo(o1.getSortKey().toString());
        });
        List<UserVO> userModels = Lists.newArrayList(userSelectionVOS);
        //将主管排序在前面
        sortByManager(userModels);
        userSelectionVOS.clear();
        userModels.forEach(m -> userSelectionVOS.add((UserSelectionVO) m));
    }

    /**
     * 管理员排序，管理员排在前面
     *
     * @param userSelectionVOS
     */
    private void sortByManager(List<UserVO> userSelectionVOS) {
        if (CollectionUtils.isEmpty(userSelectionVOS)) {
            return;
        }
        List<UserVO> temp = new ArrayList<>();
        Iterator<UserVO> iterator = userSelectionVOS.iterator();
        while (iterator.hasNext()) {
            UserVO next = iterator.next();
            if (next.getLeader()) {
                temp.add(next);
                iterator.remove();
            } else {
                List<RoleUserModel> roleUserModelList = getOrganizationFacade().getRoleUsersByUserId(next.getId());
                if (CollectionUtils.isNotEmpty(roleUserModelList)) {
                    List<String> collect = roleUserModelList.stream().map(roleUserModel -> roleUserModel.getRoleId()).collect(Collectors.toList());
                    List<RoleModel> roleModelList = getOrganizationFacade().getRolesByIds(collect);
                    if (CollectionUtils.isNotEmpty(roleModelList)) {
                        List<String> collect1 = roleModelList.stream().map(roleModel -> roleModel.getName()).collect(Collectors.toList());
                        if (collect1.contains("主管")) {
                            temp.add(next);
                            iterator.remove();
                        }
                    }
                }
            }
        }
        userSelectionVOS.addAll(0, temp);
    }


    //多组织选人控件过滤
    private void filterUserByOrgType(List<UserSelectionVO> userSelectionVOS) {
        String userId = getUserId();
        UserModel user = getOrganizationFacade().getUser(userId);
        RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(user.getCorpId());
        if (Objects.nonNull(relatedCorpSettingModel)) {
            switch (relatedCorpSettingModel.getOrgType()) {
                case RELEVANCE:
                    if (!org.springframework.util.CollectionUtils.isEmpty(userSelectionVOS)) {
                        Iterator<UserSelectionVO> iterator = userSelectionVOS.iterator();
                        while (iterator.hasNext()) {
                            UserSelectionVO next = iterator.next();
                            if (!next.getCorpId().equals(relatedCorpSettingModel.getCorpId())) {
                                iterator.remove();
                            }
                        }
                    }
                    break;
            }
        }
    }


    /**
     * @return UserVO
     * @Description: 添加所属角色字段
     * @Param [pageable, userPage]
     * @author dengchao
     * @date 2018/11/1 14:46
     */
    private void setRoleName(List<UserVO> userVOList) {
        //添加所属角色字段
        List<String> idList = userVOList
                .stream().filter(Objects::nonNull).map(BaseModel::getId).collect(Collectors.toList());
        Map<String, List<RoleModel>> roleNameMap;
        if (!idList.isEmpty()) {
            roleNameMap = getOrganizationFacade().getRolesByUserIds(idList);
            if (MapUtils.isNotEmpty(roleNameMap)) {
                userVOList.forEach(userVO -> {
                    List<RoleModel> roleList = roleNameMap.get(userVO.getId());
                    if (!CollectionUtils.isEmpty(roleList)) {
                        List<String> roleNameList = roleList.stream().filter(Objects::nonNull).map(RoleModel::getName).collect(Collectors.toList());
                        userVO.setRoleName(String.join(",", roleNameList));
                    }
                });
            }
        }
    }

    /**
     * @return List<UserVO>
     * @Description: 过滤用户视图对象
     * @Param [userList]
     * @author dengchao
     * @date 2018/11/7 19:14
     */
    private List<UserVO> getUserVOList(List<UserModel> userList) {
        return userList.stream().filter(Objects::nonNull).map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
    }


    @GetMapping("/generate_organization")
    @ApiOperation(value = "生成组织机构", notes = "生成组织机构数据, 引擎异步处理, 默认创建1110个部门(部门分三级, 一级10个, 二级100个, 三级部门1000个), 55500用户(每个部门下有50个用户), 100角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptNum", value = "部门数量", dataType = "Integer", paramType = "path", defaultValue = "''"),
            @ApiImplicitParam(name = "userNum", value = "部门下用户数量", dataType = "Integer", paramType = "path", defaultValue = "''")
    })
    public ResponseResult<Boolean> generateOrganization(@RequestParam int deptNum, @RequestParam int userNum) {
        Boolean result = getOrganizationFacade().generateOrganizationData(deptNum, userNum);
        return getOkResponseResult(result, "数据生成完成");
    }

    @GetMapping("/get_max_department_level")
    @ApiOperation(value = "获取组织结构最大等级数", notes = "获取组织结构最大等级数")
    public ResponseResult<Integer> getMaxDepartmentLevel() {
        int result = getOrganizationFacade().getMaxDepartmentLevel();
        return getOkResponseResult(result, "组织机构最长层级查询成功");
    }

    @GetMapping("/get_user_parent_depts")
    @ApiOperation(value = "获取用户的父级部门", notes = "获取组织结构最大等级数")
    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String", paramType = "query")
    public ResponseResult<List<DepartmentModel>> getUserParentDepartments(@RequestParam String userId) {
        UserModel user = getOrganizationFacade().getUser(userId);
        if (user == null) {
            return getOkResponseResult(new ArrayList<>(), "id为 " + userId + "的用户不存在");
        }
        List<DepartmentModel> parentDepartments = getOrganizationFacade().getParentDepartments(user.getDepartmentId());
        Collections.reverse(parentDepartments);

        return getOkResponseResult(parentDepartments, "获取用户的父级部门成功");
    }

    @ApiOperation(value = "部门导出接口")
    @ApiImplicitParam(name = "deptIds", value = "部门导出接口,部门id集合", required = true, dataType = "query")
    @PostMapping("/export_dept")
    public void exportDeptData(@RequestBody List<String> deptIds, HttpServletResponse response) {
        long startTimeExport = System.currentTimeMillis();
        if (CollectionUtils.isEmpty(deptIds)) {
            throw new PortalException(ResultEnum.ILLEGAL_PARAMETER_ERR.getErrCode(), "导出部门不能为空");
        }
        //需要导出的部门集合
        List<DepartmentModel> departmentModels = getOrganizationFacade().getDepartmentsByDeptIds(deptIds);
        List<Map<String, Object>> datas = new ArrayList<>();

        AdminModel adminModel = getAppAdminByUserId(getUserId());

        //获取所有子部门（包括叶子节点）
        departmentModels.stream().forEach(dept -> getChildsByDeptId(dept, adminModel));

        for (DepartmentModel model : departmentModels) {
            if (model.getDeleted()) {
                continue;
            }
            String deptPath = selectionHelper.getDeptPath(model.getId());
            //拼装导出部门名称
            addDeptNameMap(datas, deptPath);
            //拼装子部门及其下所有子孙...部门名称
            getDeptNames(model, datas, new StringBuilder(deptPath), "deptName", true);
        }
        List<ExportCommonHelper.ExportColumn> columns = new ArrayList<>();
        columns.add(new ExportCommonHelper.ExportColumn("deptName", "部门名称"));
        try {
            ExportCommonHelper.export(response, columns, datas, false);
        } catch (Exception e) {
            log.error("部门导出失败", e);
            throw new PortalException(304030L, "部门导出失败");
        }
        long endTimeExport = System.currentTimeMillis();
        log.info("导出总时间：--{}", endTimeExport - startTimeExport);
    }

    private void addDeptNameMap(List<Map<String, Object>> datas, String deptPath) {
        Map<String, Object> map = new HashMap<>();
        map.put("deptName", deptPath);
        datas.add(map);
    }

    //根据部门id获取旗下所有的子部门，包括子部门的子部门,子子部门，...
    private void getChildsByDeptId(DepartmentModel departmentModel, AdminModel adminModel) {
        List<DepartmentModel> childrens = getOrganizationFacade().getDepartmentsByParentId(departmentModel.getId());
        if (CollectionUtils.isEmpty(childrens)) {
            return;
        }

        childrens = filterManagerDept(adminModel, childrens);
        departmentModel.setChildren(childrens);
        Iterator<DepartmentModel> iterator = childrens.iterator();
        while (iterator.hasNext()) {
            DepartmentModel child = iterator.next();
            if (child.getIsShow()) {
                getChildsByDeptId(child, adminModel);
            } else {
                iterator.remove();
            }
        }
    }

    /**
     * 获取部门下面的所有部门名称的拼接，按照：父部门/子部门/孙部门... 的规格
     *
     * @param departmentModel
     * @param flag            是否用户传入的导出部门而非子孙...部门
     * @return
     */
    private void getDeptNames(DepartmentModel departmentModel, List<Map<String, Object>> deptNameList, StringBuilder deptNameStr, String key, boolean flag) {
        if (deptNameList == null) {
            deptNameList = new ArrayList();
        }
        List<DepartmentModel> childrens = departmentModel.getChildren();
        if (CollectionUtils.isNotEmpty(childrens)) {
            //是叶子节点，但还有子项目，说明子部门已经被删除完
            if (departmentModel.getLeaf() && !flag) {
                addDeptNameMap(deptNameList, deptNameStr.toString());
                return;
            }
            for (DepartmentModel child : childrens) {
                if (child.getDeleted()) {
                    continue;
                }
                StringBuilder sb = new StringBuilder();
                sb.append(deptNameStr).append("/").append(child.getName());
                if (!child.getLeaf()) {
                    addDeptNameMap(deptNameList, sb.toString());
                }
                getDeptNames(child, deptNameList, sb, key, false);
            }

        } else {
            if (flag) {
                return;
            }
            addDeptNameMap(deptNameList, deptNameStr.toString());
        }
    }

    @ApiOperation(value = "用户导出接口")

    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "导出用户数据模型： {\"deptId\":\"\",\"userIds\":[\"]}", dataType = "query"
            )
    })
    @PostMapping("/export_user")
    public void exportUserData(@RequestBody ExportUser exportUser, HttpServletResponse response) {
        long startTimeExport = System.currentTimeMillis();
        List<String> userIds = exportUser.getUserIds();
        String deptId = exportUser.getDeptId();
        if (CollectionUtils.isEmpty(userIds) && StringUtils.isBlank(deptId)) {
            log.error("没有选择部门或者用户:userIds={},deptId={}", exportUser.getUserIds(), exportUser.getDeptId());
            throw new PortalException(ResultEnum.ILLEGAL_PARAMETER_ERR.getErrCode(), "没有选择部门或者用户");
        }

        List<ExportCommonHelper.ExportColumn> columns = getUserExportColumns();
        List<UserModel> userVOS = getUsers(userIds, deptId);
        removeRepeatUser(userVOS);
        List<Map<String, Object>> datas = getUserExportDataMaps(userVOS);
        log.info("导出：--{}", datas);
        try {
            ExportCommonHelper.export(response, columns, datas, false);
        } catch (Exception e) {
            log.error("用户导出失败,{}", e);
            throw new PortalException(304030L, "用户导出失败");
        }
        long endTimeExport = System.currentTimeMillis();
        log.info("导出总时间：--{},导出总数据是：--{}", endTimeExport - startTimeExport, datas.size());
    }

    //去重，避免有多个部门时导出重复
    private void removeRepeatUser(List<UserModel> userVOS) {
        if (CollectionUtils.isNotEmpty(userVOS)) {
            Iterator<UserModel> iterator = userVOS.iterator();
            ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
            while (iterator.hasNext()) {
                UserModel userModel = iterator.next();
                Integer integer = concurrentHashMap.putIfAbsent(userModel.getId(), 1);
                if (integer != null) {
                    iterator.remove();
                }
            }
        }
    }

    private List<UserModel> getUsers(List<String> userIds, String deptId) {
        OrganizationFacade organizationFacade = getOrganizationFacade();
        if (CollectionUtils.isEmpty(userIds)) {
            /*            */
            //登录用户
            String userId = getUserId();
            AdminModel appAdminByUser = getAppAdminByUserId(userId);
            if (appAdminByUser != null) {
                switch (appAdminByUser.getAdminType()) {
                    case ADMIN:
                    case SYS_MNG:
                        userIds = getUsersByDept(deptId);
                        break;
                    case APP_MNG:
                        UserModel user = organizationFacade.getUser(userId);
                        userIds = getUsersByDept(user.getDepartmentId());
                        break;
                    default:
                        return new ArrayList<>();
                }
            } else {
                //ADMIN用户
                userIds = getUsersByDept(deptId);
            }
        }
        Map<String, UserModel> users = organizationFacade.getUsers(userIds);
        List<UserModel> collect = userIds.stream().map(userId -> users.get(userId)).collect(Collectors.toList());
        return collect;
    }

    private List<String> getUsersByDept(String deptId) {
        List<String> userIds;
        OrganizationFacade organizationFacade = getOrganizationFacade();
        DepartmentModel department = organizationFacade.getDepartment(deptId);
        getChildsByDeptId(department, null);
        List<String> deptIds = getDeptIds(department, null);
        List<UserModel> userModels = new ArrayList<>();
        for (String id : deptIds) {
            userModels.addAll(organizationFacade.getUsersByDeptId(id));
        }

        userIds = userModels.stream().map(userModel -> userModel.getId()).collect(Collectors.toList());
        return userIds;
    }

    private List<String> getDeptIds(DepartmentModel department, List<String> deptIds) {
        if (deptIds == null) {
            deptIds = new ArrayList<>();
        }
        deptIds.add(department.getId());
        List<DepartmentModel> children = department.getChildren();
        if (CollectionUtils.isNotEmpty(children)) {
            for (DepartmentModel child : children) {
                getDeptIds(child, deptIds);
            }
        }

        return deptIds;
    }

    private List<Map<String, Object>> getUserExportDataMaps(List<UserModel> userVOS) {
        List<Map<String, Object>> datas = new ArrayList<>();
        for (UserModel userVO : userVOS) {
            if (userVO == null) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("username", userVO.getUsername());
            map.put("name", userVO.getName());
            map.put("mobile", userVO.getMobile());
            map.put("email", userVO.getEmail());
            map.put("officePhone", userVO.getOfficePhone());
            map.put("employeeNo", userVO.getEmployeeNo());
            map.put("entryDate", userVO.getEntryDate() == null ? null : DateUtils.getDate(userVO.getEntryDate(), "yyyy-MM-dd"));
            //組裝部门
            buildDeptPath(userVO, map);
            //组装角色
            map.put("role", getUserRole(userVO.getId()));
            datas.add(map);
        }
        return datas;
    }

    //获取用户所有角色数据，并拼接起来，用符号;分开
    private Object getUserRole(String userId) {
        List<RoleUserModel> roleUserModels = getOrganizationFacade().getRoleUsersByUserId(userId);
        if (CollectionUtils.isNotEmpty(roleUserModels)) {
            StringBuilder sb = new StringBuilder();
            for (RoleUserModel roleUserModel : roleUserModels) {
                String roleId = roleUserModel.getRoleId();
                RoleModel role = getOrganizationFacade().getRole(roleId);
                sb.append(role.getName()).append(";");
            }
            if (sb.length() > 0) {
                sb.delete(sb.length() - 1, sb.length());
            }
            return sb;
        }
        return null;
    }

    private void buildDeptPath(UserModel userVO, Map<String, Object> map) {
        List<DepartmentUserModel> departmentUserModels = getOrganizationFacade().getDepartmentUsersByUserId(userVO.getId());
        if (CollectionUtils.isNotEmpty(departmentUserModels)) {
            for (DepartmentUserModel departmentUserModel : departmentUserModels) {
                if (userVO.getDepartmentId().equals(departmentUserModel.getDeptId())) {
                    String deptPath = selectionHelper.getDeptPath(departmentUserModel.getDeptId());
                    Object mainDept = map.get("mainDept");
                    if (Objects.nonNull(mainDept)) {
                        map.put("mainDept", mainDept + ";" + deptPath);
                    } else {
                        map.put("mainDept", deptPath);
                    }
                } else {
                    String deptPath = selectionHelper.getDeptPath(departmentUserModel.getDeptId());
                    Object partDept = map.get("partDept");
                    if (Objects.nonNull(partDept)) {
                        map.put("partDept", partDept + ";" + deptPath);
                    } else {
                        map.put("partDept", deptPath);
                    }
                }
            }
        }
    }

    private List<ExportCommonHelper.ExportColumn> getUserExportColumns() {
        List<ExportCommonHelper.ExportColumn> columns = new ArrayList<>();
        columns.add(new ExportCommonHelper.ExportColumn("username", "用户账号"));
        columns.add(new ExportCommonHelper.ExportColumn("name", "用户姓名"));
        columns.add(new ExportCommonHelper.ExportColumn("mobile", "手机号码"));
        columns.add(new ExportCommonHelper.ExportColumn("mainDept", "所属主部门"));
        columns.add(new ExportCommonHelper.ExportColumn("partDept", "兼职部门"));
        columns.add(new ExportCommonHelper.ExportColumn("role", "角色"));
        columns.add(new ExportCommonHelper.ExportColumn("email", "邮箱"));
        columns.add(new ExportCommonHelper.ExportColumn("officePhone", "办公电话"));
        columns.add(new ExportCommonHelper.ExportColumn("employeeNo", "员工编号"));
        columns.add(new ExportCommonHelper.ExportColumn("entryDate", "入职时间"));
        return columns;
    }

    @ApiOperation(value = "部门导入接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileName", value = "文件名称", required = true, dataType = "String", paramType = "query")
    })
    @GetMapping("/import_data")
    public ResponseResult<FileOperationResult> importData(@NotBlank(message = FILE_NAME_NOT_EMPTY) @RequestParam String fileName
    ) {

        String userId = this.getUserId();

        log.debug("用户id为={}", userId);
        FileOperationResult fileOperationResult = new FileOperationResult();

        String[] fileNameArray = fileName.split("\\.");
        if (!"xlsx".equals(fileNameArray[1]) && !"xls".equals(fileNameArray[1])) {
            fileOperationResult.setErrorType(2);
            fileOperationResult.setOperationResult(false);
            fileOperationResult.setErrorMsg("不支持的导入格式");

            return this.getErrResponseResult(fileOperationResult, ErrCode.UNKNOW_ERROR.getErrCode(), "操作失败");
        }
        List<DepartmentModel> rootDepartments = getOrganizationFacade().getRootDepartment();
        if (CollectionUtils.isEmpty(rootDepartments)) {
            fileOperationResult.setErrorType(2);
            fileOperationResult.setOperationResult(false);
            fileOperationResult.setErrorMsg("当前系统没有部门根部门，请设置根部门后再导入");

            return this.getErrResponseResult(fileOperationResult, ErrCode.UNKNOW_ERROR.getErrCode(), "操作失败");
        }
        fileOperationResult.setSuccessCount(0);
        fileOperationResult.setErrorCount(0);
        fileOperationResult.setOperationResult(true);

        springThreadTask.importDepartments(userId, fileName);
        return this.getOkResponseResult(fileOperationResult, "操作成功");
    }


    @ApiOperation(value = "部门数据模板导出接口")
    @GetMapping("/export_template")
    public void exportTemplate(HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        map.put("deptname", "请输入部门全路径；如：深圳xx公司/研发中心/xx研发");
        List<Map<String, Object>> datas = Lists.newArrayList(map);
        FileOperateHelper.exportData(response, Lists.newArrayList("部门名称"), "部门", datas, null, false);
    }

    @PostMapping("/add")
    @ApiOperation(value = "云枢维护创建部门", notes = "云枢维护创建部门")
    @ApiImplicitParam(name = "deptVO", value = "{\"parentId\":\"上级部门ID\",\"name\":\"部门名称\"" +
            ",\"scopeModel\":\"编辑部门域设置，举例：{'departmentId':'部门ID','deptVisibleType':'ALL_VISIBLE,PART_VISIBLE,NOT_VISIBLE'," +
            "'deptVisibleScope':'[{'id':'主键id','name':'名称','unitType':'选项类型1：部门，2：角色，3：用户'}]'," +
            "'staffVisibleType':'ALL_VISIBLE,PART_VISIBLE,ONESELF,ONLY_DEPT','staffVisibleScope':'[{'id':'主键id','name':'名称','unitType':'选项类型1：部门，2：角色，3：用户'}]'}\"}",
            dataType = "DepartmentVO")
    public ResponseResult<DepartmentVO> createdDept(@RequestBody DepartmentVO departmentVO) {
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);

        ResponseResult<DepartmentVO> responseResult = deptHelper.create(departmentVO);
        if (ErrCode.OK.getErrCode() == responseResult.getErrcode()) {
            String userId = this.getUserId();
            removeManagePermChildDepartmentId(userId);
            SelectionScopeModel scopeModel = departmentVO.getScopeModel();
            if (Objects.nonNull(scopeModel)) {
                validateNotEmpty(scopeModel.getDeptVisibleType(), "部门可见性不能为空");
                if (DeptVisibleType.PART_VISIBLE.toString().equals(scopeModel.getDeptVisibleType())) {
                    validateNotEmpty(scopeModel.getDeptVisibleScope(), "指定人/部门不能为空");
                }
                validateNotEmpty(scopeModel.getStaffVisibleType(), "部门成员可见范围不能为空");
                if (StaffVisibleType.PRAT_VISIBLE.toString().equals(scopeModel.getStaffVisibleType())) {
                    validateNotEmpty(scopeModel.getStaffVisibleScope(), "指定人/部门不能为空");
                }

                DepartmentVO deptVo = responseResult.getData();
                scopeModel.setCreatedBy(deptVo.getCreatedBy());
                scopeModel.setDepartmentId(deptVo.getId());
                getPermissionManagementFacade().saveSelectionScope(scopeModel);
                executorService.submit(()-> selectionHelper.cacheDept(departmentVO.getId()));
            }
        }
        return responseResult;
    }

    @PostMapping("/modefied")
    @ApiOperation(value = "云枢维护编辑部门", notes = "云枢维护编辑部门")
    @ApiImplicitParam(name = "deptVO", value = "{\"parentId\":\"上级部门ID\",\"name\":\"部门名称\",\"managerId\":\"部门主管userID\",\"id\":\"部门ID\"，\"scopeModel\":\"编辑部门域设置，举例：{'departmentId':'部门ID','deptVisibleType':'ALL_VISIBLE,PART_VISIBLE,NOT_VISIBLE'," +
            "'deptVisibleScope':'[{'id':'主键id','name':'名称','unitType':'选项类型1：部门，2：角色，3：用户'}]'," +
            "'staffVisibleType':'ALL_VISIBLE,PART_VISIBLE,ONESELF,ONLY_DEPT','staffVisibleScope':'['id':'主键id','name':'名称','unitType':'选项类型1：部门，2：角色，3：用户']'}\"}",
            dataType = "DepartmentVO")
    public ResponseResult<DepartmentVO> modifyDept(@RequestBody DepartmentVO departmentVO) {
        if (departmentVO != null) {
            RelatedCorpSettingModel relatedCorpSettingModel = dubboConfigService.getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(departmentVO.getCorpId());
            if (relatedCorpSettingModel != null) {
                departmentVO.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
                departmentVO.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
            }
        }
        String newParentId = departmentVO.getParentId();
        DepartmentModel oldDept = getOrganizationFacade().getDepartment(departmentVO.getId());
        String oldParentId = oldDept == null ? "" : oldDept.getParentId();
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);
        ResponseResult<DepartmentVO> responseResult = deptHelper.update(departmentVO);
        if (ErrCode.OK.getErrCode() == responseResult.getErrcode()) {
            if (StringUtils.isNotEmpty(oldParentId) && !oldParentId.equals(newParentId)) {
                //更新子部门的querycode
                long l = System.currentTimeMillis();
                updateChildDeptQueryCode(departmentVO.getId());
                if(log.isDebugEnabled()) {
                    log.debug("递归更新子部门（queryCode）时间：{}毫秒", System.currentTimeMillis() - l);
                }
            }
            String userId = this.getUserId();
            removeManagePermChildDepartmentId(userId);
            SelectionScopeModel scopeModel = departmentVO.getScopeModel();
            if (Objects.nonNull(scopeModel)) {
                validateNotEmpty(scopeModel.getDeptVisibleType(), "部门可见性不能为空");
                if (DeptVisibleType.PART_VISIBLE.toString().equals(scopeModel.getDeptVisibleType())) {
                    validateNotEmpty(scopeModel.getDeptVisibleScope(), "指定人/部门不能为空");
                }
                validateNotEmpty(scopeModel.getStaffVisibleType(), "部门成员可见范围不能为空");
                if (StaffVisibleType.PRAT_VISIBLE.toString().equals(scopeModel.getStaffVisibleType())) {
                    validateNotEmpty(scopeModel.getStaffVisibleScope(), "指定人/部门不能为空");
                }
                scopeModel.setModifiedBy(responseResult.getData().getModifiedBy());
                getPermissionManagementFacade().saveSelectionScope(scopeModel);
                executorService.submit(()-> selectionHelper.cacheDept(departmentVO.getId()));
            }
        }
        return responseResult;
    }

    private void updateChildDeptQueryCode(String id) {
        List<DepartmentModel> firstChildDept = getOrganizationFacade().getDepartmentsByParentId(id, true);
        firstChildDept.parallelStream().forEach(dept -> {
            //update方法会直接更新querycode
            getOrganizationFacade().updateDepartment(dept);
            updateChildDeptQueryCode(dept.getId());
        });
    }

    @GetMapping("/strike_out")
    @ApiOperation(value = "云枢维护删除部门", notes = "云枢维护删除部门")
    @ApiImplicitParam(name = "id", value = "部门id", dataType = "String", defaultValue = "")
    public ResponseResult<String> strikeOutDept(@RequestParam String id) {
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);
        ResponseResult<String> deleteRes = deptHelper.delete(id);
        if (Objects.nonNull(deleteRes) && deleteRes.getErrcode() == ErrCode.OK.getErrCode()) {
            getPermissionManagementFacade().deleteSelectionScope(id);
        }
        return deleteRes;
    }

    @GetMapping("/modified_root")
    @ApiOperation(value = "编辑组织根节点名称", notes = "编辑组织根节点名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名称", required = true, dataType = "String", defaultValue = ""),
            @ApiImplicitParam(name = "corpId", value = "corpId", required = false, dataType = "String", defaultValue = "")
    })
    public ResponseResult<String> modified(@RequestParam String name, @RequestParam(required = false, defaultValue = "") String corpId) {
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);
        return deptHelper.modified(corpId, name, getUserId());
    }

    @GetMapping("/search_dept_detail")
    @ApiOperation(value = "云枢维护查找部门详情", notes = "云枢维护查找部门详情")
    @ApiImplicitParam(name = "deptId", value = "部门deptId", dataType = "String", defaultValue = "")
    public ResponseResult<DeptVO> searchDeptDetail(@RequestParam String deptId) {
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);
        ResponseResult<DeptVO> deptVO = deptHelper.searchById(deptId);
        if (Objects.nonNull(deptVO) && deptVO.getErrcode() == ErrCode.OK.getErrCode()) {
            SelectionScopeModel selectionScope = getPermissionManagementFacade().getSelectionScope(deptId);
            DeptVO data = deptVO.getData();
            if (Objects.nonNull(data) && Objects.nonNull(selectionScope)) {
                data.setScopeModel(selectionScope);
            }
        }
        return deptVO;
    }

    @GetMapping("/search_root_detail")
    @ApiOperation(value = "云枢维护查找根节点详情", notes = "云枢维护查找根节点详情")
    public ResponseResult<List<DeptVO>> searchRootDetail() {
        DeptHelper deptHelper = new DeptHelper(dubboConfigService, redisCacheService);
        return deptHelper.searchRoot();
    }

    @GetMapping("/get_dept_info")
    @ApiOperation(value = "获取部门包括组织参数", notes = "获取部门包括组织参数")
    public ResponseResult<DepartmentModel> getDeptInfo(String deptId) {
        DepartmentModel department = getOrganizationFacade().getDepartment(deptId);
        if (department == null) {
            return getOkResponseResult(null, "部门不存在");
        }

        AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
        Set<String> deptIds = Sets.newHashSet();
        boolean isAppMng = false;
        if (appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
            deptIds = getManagePermChildDepartmentId(getUserId());
            isAppMng = true;
        }
        RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(department.getCorpId());
        if (relatedCorpSettingModel != null) {
            department.setRelatedOrgType(relatedCorpSettingModel.getOrgType());
            if (isAppMng) {
                if (CollectionUtils.isNotEmpty(deptIds) && deptIds.contains(department.getId())) {
                    department.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
                }
            } else {
                department.setRelatedSyncType(relatedCorpSettingModel.getSyncType());
            }
        }
        if (isAppMng && !deptIds.contains(deptId)) {
            //没有应用管理员权限
            department.setDisplayOption(false);
        }

        //设置是否是企业的根节点
        DepartmentModel corpRootDept = getOrganizationFacade().getRootDepartmentByCorpId(department.getCorpId());
        if (corpRootDept != null && corpRootDept.getId().equals(department.getId())) {
            department.setIsCorpRootNode(Boolean.TRUE);
        }

        return getOkResponseResult(department, "成功");
    }

    @ApiOperation(value = "同步部门到组织上", notes = "同步部门到关联组织上")
    @PostMapping("/pushToDingTalk")
    @ResponseBody
    public ResponseResult pushToDingTalk(@RequestBody DepartmentUserModel[] departmentUserModels) {
        log.info("同步部门，用户到钉钉参数：{}", departmentUserModels);
        com.authine.cloudpivot.engine.api.model.ResponseResult result = null;

        //检查钉钉配置
        Set<String> corpIdSet = new HashSet<>();
        List<String> deptIds = Arrays.asList(departmentUserModels).stream().filter(dept -> StringUtils.isNotEmpty(dept.getDeptId())).map(DepartmentUserModel::getDeptId).collect(Collectors.toList());
        List<String> userIds = Arrays.asList(departmentUserModels).stream().filter(user -> StringUtils.isNotEmpty(user.getUserId())).map(DepartmentUserModel::getUserId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(deptIds)) {
            corpIdSet.addAll(getOrganizationFacade().getDepartmentsByDeptIds(deptIds).stream().map(DepartmentModel::getCorpId).collect(Collectors.toSet()));
        }
        if (CollectionUtils.isNotEmpty(userIds)) {
            corpIdSet.addAll(getOrganizationFacade().getUsers(userIds).values().stream().map(UserModel::getCorpId).collect(Collectors.toSet()));
        }
        checkDingTalkSetting(corpIdSet);
        try {
            result = getOrganizationFacade().pullDeptToDingDing(Arrays.asList(departmentUserModels));

            log.info("同步信息-{}", result);
        } catch (Exception e) {
            result = com.authine.cloudpivot.engine.api.model.ResponseResult.builder()
                    .errcode(ResultEnum.DING_SYNC_ERR.getErrCode().intValue())
                    .errmsg(ResultEnum.DING_SYNC_ERR.getErrMsg()).build();
        }

        if (result.getErrcode() == ErrCode.OK.getErrCode()) {
            return ResponseResult.<Void>builder()
                    .errcode(ResultEnum.SUCCESS.getErrCode())
                    .errmsg(ResultEnum.SUCCESS.getErrMsg())
                    .build();
        } else {

            return ResponseResult.builder()
                    .errcode(ResultEnum.UNKNOWN_ERROR.getErrCode())
                    .errmsg(JSON.toJSONString(result.getData()))
                    .data(result.getData())
                    .build();
        }
    }

    /**
     * 检查钉钉同步配置
     *
     * @param corpIds
     */
    private void checkDingTalkSetting(Set<String> corpIds) {
        if (corpIds.size() == 0) {
            return;
        }
        List<RelatedCorpSettingModel> allRelatedCorpSettingModel = getSystemManagementFacade().getAllRelatedCorpSettingModel();
        for (RelatedCorpSettingModel relatedCorpSettingModel : allRelatedCorpSettingModel) {
            if (StringUtils.isNotEmpty(relatedCorpSettingModel.getCorpId()) && !corpIds.contains(relatedCorpSettingModel.getCorpId())) {
                continue;
            }
            if (StringUtils.isEmpty(relatedCorpSettingModel.getCorpSecret()) || StringUtils.isEmpty(relatedCorpSettingModel.getAppkey())
                    || StringUtils.isEmpty(relatedCorpSettingModel.getAppSecret()) || StringUtils.isEmpty(relatedCorpSettingModel.getAgentId())
                    || StringUtils.isEmpty(relatedCorpSettingModel.getScanAppId()) || StringUtils.isEmpty(relatedCorpSettingModel.getScanAppSecret())
                    || StringUtils.isEmpty(relatedCorpSettingModel.getCorpId())) {
                throw new PortalException(ErrCode.DING_TALK_CONFIG_EMPTY.getErrCode(), "【" + relatedCorpSettingModel.getName() + "】钉钉集成参数缺失，请补全");
            }
        }

    }

    @ApiOperation(value = "根据corpId获取所有钉钉部门", notes = "获取钉钉所有部门")
    @GetMapping("/getAllDingDepts")
    @ResponseBody
    @ApiImplicitParam(name = "corpId", value = "企业的corpId", dataType = "String", defaultValue = "")
    @Deprecated
    public ResponseResult getAllDingDepts(@RequestParam String corpId) {
        validateNotEmpty(corpId);
        RelatedCorpSettingModel relatedCorpSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(corpId);
        if (CorpRelatedType.DINGTALK == relatedCorpSettingModel.getRelatedType()) {
            return getOkResponseResult(getOrganizationFacade().getAllDingDepts(corpId, Boolean.TRUE), "获取钉钉部门信息成功");
        } else if (CorpRelatedType.WECHAT == relatedCorpSettingModel.getRelatedType()) {
            return getOkResponseResult(getOrganizationFacade().getAllSourceDepts(corpId), "获取第三方部门信息成功");
        } else {
            return getErrResponseResult(ErrCode.UNKNOW_ERROR.getErrCode(), "未知组织类型");
        }
    }

    @ApiOperation(value = "根据corpId获取所有第三方部门", notes = "根据corpId获取所有第三方部门")
    @GetMapping("/getAllSourceDepts")
    @ResponseBody
    @ApiImplicitParam(name = "corpId", value = "企业的corpId", dataType = "String")
    public ResponseResult getAllSourceDepts(@RequestParam String corpId) {
        validateNotEmpty(corpId);
        return getOkResponseResult(getOrganizationFacade().getAllSourceDepts(corpId), "获取第三方部门信息成功");
    }

    @ApiOperation(value = "获取上级展示的组织机构树", notes = "获取上级展示的组织机构树（带应用管理员管理范围过滤）")
    @GetMapping("/get_all_parent_tree")
    @ResponseBody
    @ApiImplicitParam(name = "parentId", value = "parentId", dataType = "String", defaultValue = "")
    public ResponseResult<List<DepartmentModel>> getAllParentTree(@RequestParam String parentId) {
        Map<String, RelatedCorpSettingModel> relatedmap = new HashMap<>();
        getSystemManagementFacade().getAllRelatedCorpSettingModel().stream().forEach(related -> {
            relatedmap.put(related.getCorpId(), related);
        });
        //能展示的部门id
        Set<String> deptSet;
        boolean needFilter = false;
        AdminModel appAdminByUser = getAppAdminByUserId(getUserId());
        if (appAdminByUser != null && appAdminByUser.getAdminType() == AdminType.APP_MNG) {
            deptSet = getManagePermDepartmentId(getUserId());
            if (CollectionUtils.isEmpty(deptSet)) {
                return getOkResponseResult(Collections.EMPTY_LIST, "应用管理员无管理范围");
            }
            needFilter = true;
        } else {
            deptSet = new HashSet<>(2);
        }
        DepartmentModel dept = getOrganizationFacade().getDepartment(parentId);
        if (dept == null) {
            getOkResponseResult(Collections.EMPTY_LIST, "获取上级展示的组织机构树失败，部门不存在");
        }
        List<DepartmentModel> result = new ArrayList<>();
        boolean finalNeedFilter = needFilter;
        List<DepartmentModel> childList = getOrganizationFacade().getDepartmentsByParentId(dept.getId(), true).stream().filter(department -> finalNeedFilter ? deptSet.contains(department.getId()) : true && Boolean.TRUE.equals(department.getIsShow())).map(department -> {
            RelatedCorpSettingModel corp = relatedmap.get(department.getCorpId());
            if (corp != null) {
                department.setRelatedSyncType(corp.getSyncType());
                department.setRelatedOrgType(corp.getOrgType());
            }
            return department;
        }).sorted(Comparator.comparing(DepartmentModel::getSortKey, Comparator.nullsFirst(Comparator.naturalOrder())).thenComparing(DepartmentModel::getCreatedTime)).collect(Collectors.toList());
        dept.setChildren(childList);
        while (dept != null) {
            dept.setRelatedOrgType(relatedmap.get(dept.getCorpId()) == null ? null : relatedmap.get(dept.getCorpId()).getOrgType());
            dept.setRelatedSyncType(relatedmap.get(dept.getCorpId()) == null ? null : relatedmap.get(dept.getCorpId()).getSyncType());
            String deptId = dept.getId();
            List<DepartmentModel> children = dept.getChildren();
            //获取跟组织
            List<DepartmentModel> collect;
            if (StringUtils.isEmpty(dept.getParentId())) {
//                collect = getOrganizationFacade().getRootDepartment();
                collect = Lists.newArrayList(dept);
            } else {
                collect = getOrganizationFacade().getDepartmentsByParentId(dept.getParentId(), true);
            }
            collect.stream().filter(department -> finalNeedFilter ? deptSet.contains(department.getId()) : true && Boolean.TRUE.equals(department.getIsShow())).map(department -> {
                RelatedCorpSettingModel corp = relatedmap.get(department.getCorpId());
                if (corp != null) {
                    department.setRelatedSyncType(corp.getSyncType());
                    department.setRelatedOrgType(corp.getOrgType());
                }
                if (deptId.equals(department.getId())) {
                    department.setChildren(children);
                }
                return department;
            }).sorted(Comparator.comparing(DepartmentModel::getSortKey, Comparator.nullsFirst(Comparator.naturalOrder())).thenComparing(DepartmentModel::getModifiedTime)).collect(Collectors.toList());
            DepartmentModel parentDept = getOrganizationFacade().getDepartment(dept.getParentId());
            if (parentDept == null) {
                result = collect;
            } else {
                parentDept.setChildren(collect);
            }
            dept = parentDept;
        }
        return getOkResponseResult(result, "获取上级展示的组织机构树");
    }

    @ApiOperation(value = "校验 用户/部门 是否存在指定的部门集合中", notes = "校验 用户/部门 是否存在指定的部门集合中")
    @PostMapping("/orgRelationCheck")
    @ResponseBody
    public ResponseResult<Boolean> orgRelationCheck(@RequestBody OrgRelationCheckVO orgRelationCheckVO){

        if(orgRelationCheckVO.getUnitType() == null || (orgRelationCheckVO.getUnitType() != UnitType.DEPARTMENT && orgRelationCheckVO.getUnitType() != UnitType.USER)){
            return getErrResponseResult(false, ErrCode.ORG_UNIT_TYPE_ERROR.getErrCode(), ErrCode.ORG_UNIT_TYPE_ERROR.getErrMsg());
        }

        if(StringUtils.isBlank(orgRelationCheckVO.getUnitId())){
            return getErrResponseResult(false, ErrCode.ORG_UNIT_ID_NOT_NULL.getErrCode(), ErrCode.ORG_UNIT_ID_NOT_NULL.getErrMsg());
        }

        if(org.apache.commons.collections4.CollectionUtils.isEmpty(orgRelationCheckVO.getDepartmentIds())){
            return getErrResponseResult(false, ErrCode.ORG_DEPT_IDS_NOT_EMPTY.getErrCode(), ErrCode.ORG_DEPT_IDS_NOT_EMPTY.getErrMsg());
        }

        Set<String> checkDeptIds = new HashSet<>();

        String unitId = orgRelationCheckVO.getUnitId();
        if(orgRelationCheckVO.getUnitType() == UnitType.DEPARTMENT){
            DepartmentModel departmentModel = getOrganizationFacade().getDepartment(unitId, true);
            if(departmentModel == null){
                return getErrResponseResult(false, ErrCode.ORG_DEPT_QUERY_NONEXITENT.getErrCode(), ErrCode.ORG_DEPT_QUERY_NONEXITENT.getErrMsg());
            }

            checkDeptIds.add(unitId);
            checkDeptIds.addAll(getParentIdsByDepartment(unitId));
        }

        if(orgRelationCheckVO.getUnitType() == UnitType.USER){
            List<DepartmentModel> departmentList =  getOrganizationFacade().getDepartmentsByUserId(unitId, true);
            if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(departmentList)){
                departmentList.stream().forEach(departmentModel -> {
                    checkDeptIds.add(departmentModel.getId());
                    checkDeptIds.addAll(getParentIdsByDepartment(departmentModel.getId()));
                });
            }
        }

        List<String> exitIds = checkDeptIds.stream().filter(deptId -> orgRelationCheckVO.getDepartmentIds().contains(deptId)).collect(Collectors.toList());
        if(org.apache.commons.collections4.CollectionUtils.isEmpty(exitIds)){
            return getOkResponseResult(false, "组织单元在指定的部门内不存在");
        }

        return getOkResponseResult(true, "组织单元在指定的部门内");
    }

    private List<String> getParentIdsByDepartment(String departmentId){
        List<DepartmentModel> parentDepartments = getOrganizationFacade().getParentDepartments(departmentId, true);
        if(org.apache.commons.collections4.CollectionUtils.isEmpty(parentDepartments)){
            return new ArrayList<>();
        }

        return parentDepartments.stream().map(DepartmentModel::getId).collect(Collectors.toList());
    }
}

